using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 读写 scriptable object 数据
public class CharacterStats : MonoBehaviour
{
    public event Action<int, int> UpdateHealthBarOnAttack;
    public CharacterData_SO characterDataTemplate;
    public CharacterData_SO characterData;
    public AttackData_SO attackDataTemplate;
    public AttackData_SO attackData;
    private RuntimeAnimatorController baseAnimator;
    [Header("Weapon Slot")]
    public Transform weaponSlot;
    [Header("Armor Slot")]
    public Transform armorSlot;

    [HideInInspector]
    public bool isCritical;

    private void Awake()
    {
        if (characterDataTemplate != null)
        {
            characterData = Instantiate(characterDataTemplate);
        }
        if (attackDataTemplate != null)
        {
            attackData = Instantiate(attackDataTemplate);
        }
        baseAnimator = GetComponent<Animator>().runtimeAnimatorController;
    }
    // 属性寄存器 getter setter
    #region Read from scriptable object
    public int MaxHealth
    {
        get
        {
            return characterData ? characterData.maxHealth : 0;
        }
        set
        {
            characterData.maxHealth = Mathf.Max(0, value);
        }
    }
    public int CurrentHealth
    {
        get
        {
            return characterData ? characterData.currentHealth : 0;
        }
        set
        {
            characterData.currentHealth = Mathf.Max(0, value);
        }
    }
    public int BaseDefence
    {
        get
        {
            return characterData ? characterData.baseDefence : 0;
        }
        set
        {
            characterData.baseDefence = Mathf.Max(0, value);
        }
    }
    public int CurrentDefence
    {
        get
        {
            return characterData ? characterData.currentDefence : 0;
        }
        set
        {
            characterData.currentDefence = Mathf.Max(0, value);
        }
    }
    #endregion
    // Start is called before the first frame update
    #region Character Combat
    public void TakeDamage(CharacterStats atk, CharacterStats def)
    {
        int damage = Mathf.Max(0, CurrentDamage(atk) - def.CurrentDefence);
        if (atk.isCritical)
        {
            // 受击动画
            def.GetComponent<Animator>().SetTrigger("Hit");
        }
        def.CurrentHealth = Mathf.Max(0, def.CurrentHealth - damage);

        UpdateHealthBarOnAttack?.Invoke(def.CurrentHealth, def.MaxHealth);

        if (def.CurrentHealth <= 0)
        {
            atk.characterData.UpdateExp(def.characterData.killPoint);
        }
    }
    public void TakeDamage(int damage, CharacterStats def)
    {
        int currentDamage = Mathf.Max(0, damage - def.CurrentDefence);
        def.CurrentHealth = Mathf.Max(0, def.CurrentHealth - currentDamage);
        UpdateHealthBarOnAttack?.Invoke(def.CurrentHealth, def.MaxHealth);
        if (def.CurrentHealth <= 0)
        {
            GameManager.Instance.playerStat.characterData.currentExp += def.characterData.killPoint;
        }
    }
    public int CurrentDamage(CharacterStats atk)
    {
        float coreDemage = UnityEngine.Random.Range(atk.attackData.minDamage, atk.attackData.maxDamage);
        if (atk.isCritical)
        {
            coreDemage = coreDemage * atk.attackData.criticalMultiply;
        }
        return (int)coreDemage;
    }
    #endregion

    #region Equip Weapon
    // WORKFLOW: 装备武器 卸载武器 切换武器
    /// <summary>
    /// 装备武器并调用函数加成人物属性
    /// </summary>
    /// <param name="weapon">装备武器</param>
    public void EquipWeapon(ItemData_SO weapon)
    {
        // 只能装备 1 件武器
        if (weapon.weaponPrefab != null)
        {
            Instantiate(weapon.weaponPrefab, weaponSlot);
        }
        // 更新属性
        attackData.ApplyWeaponData(weapon.weaponData);
        // 切换动画
        GetComponent<Animator>().runtimeAnimatorController = weapon.weaponAnimator;
        // WORKFLOW: 切换武器、升级、使用消耗品、打开属性面板等等情况下，都需要更新属性面板
        InventoryManager.Instance.UpdateHPAndAtk(MaxHealth, attackData.minDamage, attackData.maxDamage);
    }

    public void UnEquipWeapon()
    {
        if (weaponSlot.transform.childCount > 0)
        {
            for (int i = 0; i < weaponSlot.transform.childCount; i++)
            {
                Destroy(weaponSlot.transform.GetChild(i).gameObject);
            }
        }
        attackData.ApplyWeaponData(attackDataTemplate);
        // 切换动画
        GetComponent<Animator>().runtimeAnimatorController = baseAnimator;
        // 更新属性面板
        InventoryManager.Instance.UpdateHPAndAtk(MaxHealth, attackData.minDamage, attackData.maxDamage);
    }
    public void ChangeWeapon(ItemData_SO weapon)
    {
        if (weapon != null && weapon.weaponData != null)
        {
            UnEquipWeapon();
            EquipWeapon(weapon);
        }
    }
    #endregion
    #region Apply Data Change
    // WORKFLOW: 消耗品的功能：回血
    public void ApplyHealth(int amount)
    {
        CurrentHealth = Mathf.Clamp(CurrentHealth + amount, 0, MaxHealth);
    }
    #endregion
}
